package model

import (
	"encoding/json"
	"testing"

	"github.com/stretchr/testify/assert"

	"go.mongodb.org/mongo-driver/bson"
)

type (
	VMSuit struct {
		VM   Volumes
		Json string
	}
)

func TestVolumeMountsJSON(t *testing.T) {
	strs := []string{"value"}
	suits := []VMSuit{
		{Volumes{"key": &strs[0]}, "{\"key\":\"value\"}"},
		{Volumes{"key": nil}, "{\"key\":\"null\"}"},
		{Volumes{}, "null"},
	}
	for index, value := range suits {
		actual, err := json.Marshal(&value.VM)
		if err != nil {
			t.Errorf("failed to marshall in case: %d", index)
			continue
		}
		assert.Equal(t, string(actual), string(value.Json))
	}

}

func TestVolumeMountsJSONUnmarshall(t *testing.T) {
	var testcase []byte
	var result Volumes
	//1-case
	testcase = []byte("{\"key\":\"value\"}")
	err := json.Unmarshal([]byte(testcase), &result)
	if err != nil {
		t.Errorf("failed to unmarshall in case:\n %s", testcase)
	}
	value, ok := result["key"]
	if !ok {
		t.Errorf("not key in map for:\n %s", testcase)
	}
	if *value != "value" {
		t.Errorf("not value for key in map for:\n %s", testcase)
	}
	//2-case
	var result2 Volumes
	testcase = []byte("{\"key\":\"null\"}")
	err = json.Unmarshal([]byte(testcase), &result2)
	if err != nil {
		t.Errorf("failed to unmarshall in case:\n %s", testcase)
	}
	value, ok = result2["key"]
	if !ok {
		t.Errorf("not key in map for:\n %s", testcase)
	}
	if value != nil {
		t.Errorf("not value for key in map for:\n %s", testcase)
	}
	//3-case
	var result3 Volumes
	testcase = []byte("null")
	err = json.Unmarshal([]byte(testcase), &result3)
	if err != nil {
		t.Errorf("failed to unmarshall in case:\n %s", testcase)
	}
	if len(result3) > 0 {
		t.Errorf("incorrect testing null value for %s", testcase)
	}

}

func TestVolumeMounts_bson(t *testing.T) {
	strs := []string{"value"}
	suits := []VMSuit{
		{Volumes{"key": &strs[0]}, "{\"key\":\"value\"}"},
		{Volumes{"key": nil}, "{\"key\":\"null\"}"},
		{Volumes{}, "null"},
	}
	for index, value := range suits {
		var result Volumes
		actualType, bstring, err := bson.MarshalValue(value.VM)
		if err != nil {
			t.Errorf("failed to bson marshall in case: %d", index)
			continue
		}
		raw := bson.RawValue{Type: actualType, Value: bstring}
		err = raw.Unmarshal(&result)
		if err != nil {
			t.Errorf("failed to bson unmarshall in case: %s", err)
			continue
		}
		if len(result) == len(value.VM) {
			if len(result) != 0 {
				for k, v := range value.VM {
					item, ok := result[k]
					if !ok {
						t.Errorf("not equal VolumeMounts sizes in case: %d: for key: %s", index, k)
						continue
					}
					if v != nil {
						assert.Equal(t, *v, *item)
					} else {
						if item != nil {
							t.Errorf("not equal nils sizes in case: %d: has value: %v", index, *item)
							continue
						}
					}

				}
			}
		} else {
			t.Errorf("not equal VolumeMounts sizes in case: %d", index)
		}
	}

}
